home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / games / shfflsrc.zoo / shuffle.c < prev    next >
C/C++ Source or Header  |  1991-03-16  |  15KB  |  535 lines

  1. /*
  2.     This is Shuffle, a puzzle game for the Atari ST
  3.     Copyright (C) 1991  by Robert Fischer
  4.  
  5.     This program costs no money; you may redistribute it and/or modify it
  6.     under the terms of the Lynxware General License as published by Robert
  7.     Fischer; either version 1, or (at your option) any later version. 
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     Lynxware General License for more details.
  13.  
  14.     You should have received a copy of the Lynxware General License
  15.     along with this program; if not, write to the author.
  16.  
  17.     To contact the author, call or write:
  18.         Robert Fischer
  19.         80 Killdeer Road
  20.         Hamden, CT    06517
  21.         (203) 288-9599
  22.         E-mail: fischer-robert@cs.yale.edu
  23. */
  24. /* NOTE: Shuffle requires LynxLib to compile */
  25. long _stksize = 4000L;
  26. #define THE_RESOURCE "SHUFFLE.RSC"
  27. #include <stdio.h>
  28. #include <e_osbind.h>
  29. #include <picture.h>
  30. #include <gemdefs.h>
  31. #include <aesbind.h>
  32. #include <vdibind.h>
  33. #include <mygem.h>
  34. #include <nobdefs.h>
  35. #include "shuffle.h"
  36. /* ---------------------------------------------------------------- */
  37. /* Types & constants */
  38. typedef struct {
  39.     int hand;        /* the VDI handle */
  40.     xy size;        /* Width and height of device */
  41. } vdi_hand;
  42.  
  43. /* ---------------------------------------------------------------- */
  44. /* Global Variables */
  45. vdi_hand screen;    /* VDI virtual workstation handle */
  46. int intin[128];
  47. int intout[128];
  48. int ptsin[128];
  49. int ptsout[128];
  50. int contrl[12];
  51. /* ---------------------------------------------------------------- */
  52.  
  53. /* ---------------------------------------------------------------- */
  54. /* ---------------------------------------------------------------- */
  55. fix_sizebox()    /* Fixes up the size box */
  56. {
  57. OBJECT *d;
  58. int i;
  59.     rsrc_gaddr(0, SIZEBOX, &d);
  60.  
  61.     /* Change each thing from one char high to 1 char - 1 pixel */
  62.     for (i = ACRO1; i < ACRO64; i++)
  63.         d[i].ob_height -= 1;
  64.     for (i = DOWN1; i < DOWN50; i++)
  65.         d[i].ob_height -= 1;
  66. }
  67. /* ---------------------------------------------------------------- */
  68. BOOLEAN gem_puzsize(pic, x, y)    /* Asks the user for the puzzle size */
  69. /* Returns in x & y the number of pieces for that axis */
  70. pic_rec *pic;
  71. int *x, *y;
  72. {
  73. OBJECT *d;
  74. static index_to_across[] = {1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, -1};
  75. static index_to_down[] = {1, 2, 4, 5, 8, 10, 20, 25, 40, 50, -1};
  76. register int *i;
  77. int index;
  78. int b;        /* Button used to exit */
  79.  
  80.     rsrc_gaddr(0, SIZEBOX, &d);
  81.     form_center(d, &b, &b, &b, &b);
  82.  
  83.     /* Set selected thing and clear all others */
  84.     for (i = index_to_down, index = DOWN1; *i != -1; i++, index++) {
  85.         if (*i == *y) {
  86.             d[index].ob_state |= SELECTED;
  87.         } else {
  88.             d[index].ob_state &= ~SELECTED;
  89.         }
  90.     }
  91.  
  92.     for (i = index_to_across, index = ACRO1; *i != -1; i++, index++) {
  93.         if (*i == *x) {
  94.             d[index].ob_state |= SELECTED;
  95.         } else {
  96.             d[index].ob_state &= ~SELECTED;
  97.         }
  98.     }
  99.  
  100.     draw_box(d);
  101.     do {
  102.         b = form_do(d, 0);
  103.         d[b].ob_state &= ~SELECTED;
  104.         objc_draw(d, b, 1, 0, 0, 0, 0);
  105.  
  106.         /* See if he wanted to see the picture */
  107.         if (b == PICLOOK) {
  108.             graf_mouse(M_OFF);
  109.             switch_pic(pic);
  110.             wait_mouse(LEFT_BUTTON);
  111.             switch_norm(pic);
  112.             graf_mouse(M_ON);
  113.             wait_mouse(0);
  114.         }
  115.     } while (b == PICLOOK);
  116.     undraw_box(d);
  117.  
  118.     /* Scan for selected one */
  119.     if (b == SBOK) {
  120.         for (index = ACRO1; (d[index].ob_state & SELECTED) == 0; index++);
  121.         *x = index_to_across[index - ACRO1];
  122.         for (index = DOWN1; (d[index].ob_state & SELECTED) == 0; index++);
  123.         *y = index_to_down[index - DOWN1];
  124.         return TRUE;
  125.     }
  126.     return FALSE;
  127. }
  128.  
  129. /* ---------------------------------------------------------------- */
  130. /* End of GEM stuff */
  131. /* ---------------------------------------------------------------- */
  132. static FDB f_screen = {0L, ACRO1 + 0, 0, 0, TRUE, 0, 0, 0, 0};    /* for bit blitting */
  133. blit_block(ioblock, ifdb, ofdb)
  134. xyxyxyxy ioblock;
  135. FDB *ifdb, *ofdb;
  136. {
  137.     vro_cpyfm(screen.hand, OPAQUE, &ioblock, ifdb, ofdb);
  138. }
  139. /* ---------------------------------------------------------------- */
  140. find_block(pos, squaresize)
  141. /* Finds the puzzle square that the mouse is in */
  142. register xyxy *pos;        /* Mouse position, also output */
  143. xy squaresize;            /* Size of each square */
  144. {
  145.     pos->x -= (pos->x % squaresize.x);
  146.     pos->y -= (pos->y % squaresize.y);
  147.     pos->x1 = pos->x + squaresize.x - 1;
  148.     pos->y1 = pos->y + squaresize.y - 1;
  149. }
  150. /* ---------------------------------------------------------------- */
  151. wait_mouse(state)    /* Awaits for the mouse buttons to enter the desired state */
  152. WORD state;
  153. {
  154. int i, mstate;
  155.     if (state == 0)
  156.         evnt_button(1, LEFT_BUTTON | RIGHT_BUTTON, 0, &i, &i, &i, &i);
  157.     else
  158.         evnt_button(1, state, 1, &i, &i, &i, &i);
  159. }
  160. /* ---------------------------------------------------------------- */
  161. graf_waitm(state)    /* Same as wait_mouse, only uses graf_mouse */
  162. WORD state;
  163. {
  164. int i, mstate;
  165.     do {
  166.         graf_mkstate(&i, &i, &mstate, &i);
  167.     } while (mstate != state);
  168. }
  169. /* ---------------------------------------------------------------- */
  170. BOOLEAN c_cmpmem(a, b, numlongs)
  171. register LONG *a, *b;
  172. register int numlongs;
  173. {
  174.     for (; numlongs > 0; numlongs --) {
  175.         if (*a++ != *b++) return FALSE;
  176.     }
  177.     return TRUE;
  178. }
  179. /* ---------------------------------------------------------------- */
  180. /* Generate a positive random number */
  181. unsigned int rnd(low, high)
  182. /* Generates a number between low & high, including low & excluding high */
  183. unsigned int low, high;
  184. {
  185.     return ((unsigned int)Random()) % (high - low) + low;
  186. }
  187. /* ---------------------------------------------------------------- */
  188. #ifdef NODEF
  189. func *old_etv_term;
  190. char *old_screen;
  191.  
  192. err_handler()
  193. {
  194.     SCREENPT = old_screen;
  195.     ETV_TERM = old_etv_term;
  196. }
  197.  
  198. install_err()
  199. {
  200. LONG usp;
  201.     usp = Super(0);
  202.     old_screen = V_BASE_AD;
  203.     old_etv_term = ETV_TERM;
  204.     ETV_TERM = &err_handler;
  205.     Super(usp);
  206. }
  207.  
  208. dinstall_err()
  209. {
  210. LONG usp;
  211.     usp = Super(0);
  212.     ETV_TERM = old_etv_term;
  213.     Super(usp);
  214. }
  215. #endif
  216. /* ----------------------------------------------------------- */
  217. int g_getkey()    /* Gets a key from GEM AES */
  218. /* Returns -1 if no key is available */
  219. {
  220. int i, key, event;
  221.  
  222.     event = evnt_multi(MU_KEYBD | MU_TIMER,
  223.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  224.         &i, 0, 0, &i, &i, &i, &i, &key, &i);
  225.     if (event == MU_TIMER) return -1;
  226.     return key & 0xFF;
  227. }
  228. /* ---------------------------------------------------------------- */
  229. BOOLEAN puzzle_pic(pic, squaresize)        /* Puzzles on a picture */
  230. /* Returns TRUE if you should puzzle this picture again, but with */
  231. /* a different size */
  232. pic_rec *pic;        /* Picture to puzzle on */
  233. xy squaresize;        /* Size of puzzle squares to use */
  234. {
  235. xyxy ipos, opos;    /* Block position */
  236. WORD mstate;    /* Mouse button state */
  237. WORD kstate;    /* Keyboard shift state */
  238. int c;
  239.  
  240. pic_rec *messed_pic;        /* Picture which will be destroyed */
  241.  
  242. LONG usp;
  243. char stringg[80];
  244. LONG time;
  245. char s[2];
  246.  
  247. /* For blitting */
  248. FDB temp_fdb;        /* FDB of temporary storage area */
  249. WORD *temp;        /* Pointer to temporary storage area */
  250. xy lastxy;
  251. xyxyxyxy pline;
  252. int ystart, yend, xstart, xend, xincr, yincr;
  253. xy opos_offset;        /* opos.x - ipos.x, opos.y - ipos.y */
  254.  
  255.     /* Copy the original picture */
  256.     messed_pic = malloc(sizeof(pic_rec));
  257.     messed_pic->p_start = (char *)(((LONG)(messed_pic->p) + 255) & 0xFFFFFF00L);
  258.     memcpy(messed_pic->p_start, pic->p_start, SCR_SIZE);
  259.     messed_pic->rez = pic->rez;
  260.     for (c = 0; c < 16; c++) messed_pic->pal[c] = pic->pal[c];
  261.  
  262.     graf_mouse(M_OFF);    /* Put GEM into new picture */
  263.     switch_pic(messed_pic);
  264.  
  265.     /* Set up the temporary blit buffer */
  266.     temp_fdb.fd_w = squaresize.x;
  267.     temp_fdb.fd_h = squaresize.y;
  268.     temp_fdb.fd_wdwidth = (temp_fdb.fd_w + 15) >> 4;
  269.     temp_fdb.fd_stand = TRUE;
  270.     temp_fdb.fd_nplanes = (1 << (2 - Getrez()));
  271.     temp_fdb.fd_r1 = 0;
  272.     temp_fdb.fd_r2 = 0;
  273.     temp_fdb.fd_r3 = 0;
  274.     temp = (WORD *)malloc(temp_fdb.fd_wdwidth * temp_fdb.fd_h
  275.             * 2 * temp_fdb.fd_nplanes);
  276.     temp_fdb.fd_addr = (LONG)temp;
  277.  
  278.     /* Shuffle the picture */
  279.     lastxy.x = squaresize.x - 1;
  280.     las